/**
 * 
 */
package datastructure;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author Michael
 * Given
 * interface Iterator<T> {
 * 		T next();
 * 		boolean hasNext();
 * }
 * interface Predicate<T> {
 * 		boolean accept(T t);
 * }
 * Implement a method that creates an "accept" iterator that returns items 
 * accepted by the passedin pred variable.
 * Iterator<T> conditionIterator<T>(Iterator<T> input, Predicate<T> pred) { }
 }
 */
public class AcceptIterator<T> implements Iterator<T> {

	// private members
	Iterator<T> iterator = null;
	Predicate<T> predicate = null;
	T nextElement = null;
	
	/**
	 * 
	 */
	public AcceptIterator(Iterator<T> iterator, Predicate<T> predicate) {
		this.iterator = iterator;
		this.predicate = predicate;
		this.updateNext();
	}
	
	public static <T> Iterator<T> getInstance(Iterator<T> input, Predicate<T> pred) {
		return new AcceptIterator<T>(input, pred);
	}

	private void updateNext() {
		nextElement = null;
		while (iterator.hasNext()) {
			T element = iterator.next();
			if (predicate.accept(element)) {
				nextElement = element;
				break;
			}
		}
	}
	
	@Override
	public boolean hasNext() {
		return nextElement != null;
	}

	@Override
	public T next() {
		T e = nextElement;
		this.updateNext();
		return e;
	}

	@Override
	public void remove() {
		// TODO Auto-generated method stub
		
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		List<Integer> l = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++)
			l.add(i);
		Iterator<Integer> iter = l.iterator();
		Predicate<Integer> pred = new PredicateImpl();
		Iterator<Integer> it = AcceptIterator.getInstance(iter, pred);
//		System.out.println(it.hasNext());
//		System.out.println(it.hasNext());
//		System.out.println(it.hasNext());
//		System.out.println(it.hasNext());
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		System.out.println(it.hasNext());
		System.out.println(it.hasNext());
		System.out.println(it.hasNext());
		System.out.println(it.hasNext());
	}



}

class PredicateImpl implements Predicate<Integer> {
	public boolean accept(Integer a) {
		return a % 2 == 0;
	}
}

interface Predicate<T> {
	public boolean accept(T t);
}


